package com.xlf.service.judge.strategy.judgeMachine.impl.goJudge.builder;

import com.alibaba.fastjson2.JSONObject;

/**
 * @Author xlf 2734029211@qq.com
 * @Date 2023/9/15 22:42
 * @Description: TODO https://github.com/criyle/go-judge/blob/master/README.cn.md
 * @Version 1.0
 */
public abstract class CmdBuilder {




    protected JSONObject cmd = new JSONObject();

    abstract void buildArgs();

    abstract void buildEnv();

    abstract void buildFiles();

    abstract void buildCpuLimit();

    abstract void buildMemoryLimit();

    abstract void buildClockLimit();

    abstract void buildStackLimit();

    abstract void buildProcLimit();

    abstract void buildCopyIn();

    abstract void buildCopyOut();

    abstract void buildCopyOutCached();


    /**
     *
     * @return eg:{
     *     "cmd": [{
     *         "args": ["/usr/bin/g++", "a.cc", "-o", "a"],
     *         "env": ["PATH=/usr/bin:/bin"],
     *         "files": [{
     *             "content": ""
     *         }, {
     *             "name": "stdout",
     *             "max": 10240
     *         }, {
     *             "name": "stderr",
     *             "max": 10240
     *         }],
     *         "cpuLimit": 10000000000,
     *         "memoryLimit": 104857600,
     *         "procLimit": 50,
     *         "copyIn": {
     *             "a.cc": {
     *                 "content": "#include <iostream>\nusing namespace std;\nint main() {\nint a, b;\ncin >> a >> b;\ncout << a + b << endl;\n}"
     *             }
     *         },
     *         "copyOut": ["stdout", "stderr"],
     *         "copyOutCached": ["a","a.cc"]
     *     }]
     * }
     */
    public JSONObject Commander(){

        buildArgs();
        buildEnv();
        buildFiles();
        buildCpuLimit();
        buildClockLimit();
        buildStackLimit();
        buildMemoryLimit();
        buildProcLimit();
        buildCopyIn();
        buildCopyOut();
        buildCopyOutCached();

        return cmd;
    }


}


/**
 * interface LocalFile {
 *     src: string; // 文件绝对路径
 * }
 *
 * interface MemoryFile {
 *     content: string | Buffer; // 文件内容
 * }
 *
 * interface PreparedFile {
 *     fileId: string; // 文件 id
 * }
 *
 * interface Collector {
 *     name: string; // copyOut 文件名
 *     max: number;  // 最大大小限制
 *     pipe?: boolean; // 通过管道收集（默认值为false文件收集）
 * }
 *
 * interface Symlink {
 *     symlink: string; // 符号连接目标 (v1.6.0+)
 * }
 *
 * interface Cmd {
 *     args: string[]; // 程序命令行参数
 *     env?: string[]; // 程序环境变量
 *
 *     // 指定 标准输入、标准输出和标准错误的文件
 *     files?: (LocalFile | MemoryFile | PreparedFile | Collector)[];
 *     tty?: boolean; // 开启 TTY （需要保证标准输出和标准错误为同一文件）同时需要指定 TERM 环境变量 （例如 TERM=xterm）
 *
 *     // 资源限制
 *     cpuLimit?: number;     // CPU时间限制，单位纳秒
 *     clockLimit?: number;   // 等待时间限制，单位纳秒 （通常为 cpuLimit 两倍）
 *     memoryLimit?: number;  // 内存限制，单位 byte
 *     stackLimit?: number;   // 栈内存限制，单位 byte
 *     procLimit?: number;    // 线程数量限制
 *     cpuRateLimit?: number; // 仅 Linux，CPU 使用率限制，1000 等于单核 100%
 *     cpuSetLimit?: string;  // 仅 Linux，限制 CPU 使用，使用方式和 cpuset cgroup 相同 （例如，`0` 表示限制仅使用第一个核）
 *     strictMemoryLimit?: boolean; // 开启严格内存限制 （仅 Linux，设置 rlimit 内存限制）
 *
 *     // 在执行程序之前复制进容器的文件列表
 *     copyIn?: {[dst:string]:LocalFile | MemoryFile | PreparedFile | Symlink};
 *
 *     // 在执行程序后从容器文件系统中复制出来的文件列表
 *     // 在文件名之后加入 '?' 来使文件变为可选，可选文件不存在的情况不会触发 FileError
 *     copyOut?: string[];
 *     // 和 copyOut 相同，不过文件不返回内容，而是返回一个对应文件 ID ，内容可以通过 /file/:fileId 接口下载
 *     copyOutCached?: string[];
 *     // 指定 copyOut 复制文件大小限制，单位 byte
 *     copyOutMax?: number;
 * }
 *
 * enum Status {
 *     Accepted = 'Accepted', // 正常情况
 *     MemoryLimitExceeded = 'Memory Limit Exceeded', // 内存超限
 *     TimeLimitExceeded = 'Time Limit Exceeded', // 时间超限
 *     OutputLimitExceeded = 'Output Limit Exceeded', // 输出超限
 *     FileError = 'File Error', // 文件错误
 *     NonzeroExitStatus = 'Nonzero Exit Status', // 非 0 退出值
 *     Signalled = 'Signalled', // 进程被信号终止
 *     InternalError = 'Internal Error', // 内部错误
 * }
 *
 * interface PipeIndex {
 *     index: number; // cmd 的下标
 *     fd: number;    // cmd 的 fd
 * }
 *
 * interface PipeMap {
 *     in: PipeIndex;  // 管道的输入端
 *     out: PipeIndex; // 管道的输出端
 *     // 开启管道代理，传输内容会从输出端复制到输入端
 *     // 输入端内容在输出端关闭以后会丢弃 （防止 SIGPIPE ）
 *     proxy?: boolean;
 *     name?: string;   // 如果代理开启，内容会作为 copyOut 放在输入端 （用来 debug ）
 *     // 限制 copyOut 的最大大小，代理会在超出大小之后正常复制
 *     max?: number;
 * }
 *
 * enum FileErrorType {
 *     CopyInOpenFile = 'CopyInOpenFile',
 *     CopyInCreateFile = 'CopyInCreateFile',
 *     CopyInCopyContent = 'CopyInCopyContent',
 *     CopyOutOpen = 'CopyOutOpen',
 *     CopyOutNotRegularFile = 'CopyOutNotRegularFile',
 *     CopyOutSizeExceeded = 'CopyOutSizeExceeded',
 *     CopyOutCreateFile = 'CopyOutCreateFile',
 *     CopyOutCopyContent = 'CopyOutCopyContent',
 *     CollectSizeExceeded = 'CollectSizeExceeded',
 * }
 *
 * interface FileError {
 *     name: string; // 错误文件名称
 *     type: FileErrorType; // 错误代码
 *     message?: string; // 错误信息
 * }
 *
 * interface Request {
 *     requestId?: string; // 给 WebSocket 使用来区分返回值的来源请求
 *     cmd: Cmd[];
 *     pipeMapping: PipeMap[];
 * }
 *
 * interface CancelRequest {
 *     cancelRequestId: string; // 取消某个正在进行中的请求
 * };
 *
 * // WebSocket 请求
 * type WSRequest = Request | CancelRequest;
 *
 * interface Result {
 *     status: Status;
 *     error?: string; // 详细错误信息
 *     exitStatus: number; // 程序返回值
 *     time: number;   // 程序运行 CPU 时间，单位纳秒
 *     memory: number; // 程序运行内存，单位 byte
 *     runTime: number; // 程序运行现实时间，单位纳秒
 *     // copyOut 和 pipeCollector 指定的文件内容
 *     files?: {[name:string]:string};
 *     // copyFileCached 指定的文件 id
 *     fileIds?: {[name:string]:string};
 *     // 文件错误详细信息
 *     fileError?: FileError[];
 * }
 *
 * // WebSocket 结果
 * interface WSResult {
 *     requestId: string;
 *     results: Result[];
 *     error?: string;
 * }
 */
